/*
  ==============================================================================

	PluginInfos.h
	Created: 28 Nov 2024 2:51:15pm
	Author:  leis

  ==============================================================================
*/

#pragma once
#include <JuceHeader.h>
class PluginInfo
{
public:
	juce::AudioPluginFormat* vstFomart;
	juce::PluginDescription desc;
	juce::MemoryBlock presetData;
};
class PluginInfos
{
public:
	static PluginInfos& getInstance()
	{
		static PluginInfos instance;
		return instance;
	}
	PluginInfos(const PluginInfos&) = delete;
	PluginInfos& operator=(const PluginInfos&) = delete;



	void AddPluginInfo(const char* pluginDescPath, const char* pluginPresetPath)
	{
		PluginInfo newPlugin;
		if (juce::String(pluginDescPath).contains("Vst2"))
		{
			if (vst2Format == nullptr)
			{
				vst2Format = new juce::VSTPluginFormat();
			}
			newPlugin.vstFomart = vst2Format;
		}
		else
		{
			if (vst3Format == nullptr)
			{
				vst3Format = new juce::VST3PluginFormat();
			}
			newPlugin.vstFomart = vst3Format;
		}

		juce::File pluginXmlFile(pluginDescPath);
		juce::XmlDocument pluginXmlDocument(pluginXmlFile);
		if (!pluginXmlFile.exists())
		{
			std::cout << "Failed to open plugin file: " + juce::String(pluginDescPath) << std::endl;
		}
		auto xmlElement = pluginXmlDocument.getDocumentElement();
		if (xmlElement == nullptr)
		{
			std::cout << "Failed to parse plugin xml file: " + juce::String(pluginXmlDocument.getLastParseError()) << std::endl;
			return;
		}
		juce::PluginDescription desc;
		desc.loadFromXml(*xmlElement);
		newPlugin.desc = desc;

		juce::File presetFile(pluginPresetPath);
		juce::FileInputStream presetStream(presetFile);
		if (!presetStream.openedOk())
		{
			std::cout << "Failed to open preset file: " + juce::String(pluginPresetPath) << std::endl;
		}
		juce::MemoryBlock presetData;
		presetStream.readIntoMemoryBlock(presetData);
		newPlugin.presetData = presetData;

		plugins.push_back(std::move(newPlugin));
	}
	std::vector<PluginInfo>& GetPlugins()
	{
		return plugins;
	}
	void Exit()
	{
		if (vst2Format != nullptr)
		{
			delete vst2Format;
			vst2Format = nullptr;
		}
		if (vst3Format != nullptr)
		{
			delete vst3Format;
			vst3Format = nullptr;
		}
		plugins.clear();
	}

private:
	PluginInfos() {
		vst2Format = new juce::VSTPluginFormat();
		vst3Format = new juce::VST3PluginFormat();
	}
	~PluginInfos() {
		std::cout << "PluginInfos start destroyed" << std::endl;
		if (vst2Format != nullptr)
		{
			delete vst2Format;
			vst2Format = nullptr;
		}
		if (vst3Format != nullptr)
		{
			delete vst3Format;
			vst3Format = nullptr;
		}
		plugins.clear();
		std::cout << "PluginInfos is destroyed" << std::endl;
	}

	juce::AudioPluginFormat* vst2Format;
	juce::AudioPluginFormat* vst3Format;
	std::vector<PluginInfo> plugins;
};